<template>
  <div class="category-management">
    <div class="page-header">
      <div class="title-section">
        <h1>景点类别管理</h1>
        <p class="subtitle">管理网站的景点分类，为用户提供更好的浏览体验</p>
      </div>
      <div class="action-section">
        <el-button type="primary" @click="handleAddCategory" :icon="Plus">
          添加类别
        </el-button>
      </div>
    </div>
    
    <!-- 搜索和筛选区域 -->
    <el-card class="filter-card">
      <div class="filter-container">
        <el-input
          v-model="searchQuery"
          placeholder="搜索类别名称"
          class="search-input"
          clearable
          @clear="handleSearch"
        >
          <template #prefix>
            <el-icon><Search /></el-icon>
          </template>
        </el-input>
        
        <el-select v-model="hotFilter" placeholder="热门状态" clearable @change="handleSearch">
          <el-option label="热门" :value="true" />
          <el-option label="普通" :value="false" />
        </el-select>
        
        <el-button type="primary" @click="handleSearch">搜索</el-button>
        <el-button @click="resetSearch">重置</el-button>
      </div>
    </el-card>
    
    <!-- 类别列表 -->
    <div class="category-list" v-loading="loading">
      <el-row :gutter="20">
        <el-col :xs="24" :sm="12" :md="8" :lg="6" v-for="category in categories" :key="category.categoryId">
          <el-card class="category-card" :body-style="{ padding: '0px' }">
            <div class="category-cover">
              <img :src="category.coverImage || defaultCover" alt="类别封面" />
              <div class="category-badge" v-if="category.isHot">
                <el-tag type="danger">热门</el-tag>
              </div>
            </div>
            <div class="category-info">
              <h3>{{ category.categoryName }}</h3>
              <p class="category-description">{{ category.description || '暂无描述' }}</p>
              <div class="category-meta">
                <span class="sort-order">排序: {{ category.sortOrder }}</span>
                <span class="created-time">{{ formatDate(category.createdAt) }}</span>
              </div>
              <div class="category-actions">
                <el-button type="primary" text @click="handleEditCategory(category)">
                  <el-icon><Edit /></el-icon> 编辑
                </el-button>
                <el-button type="danger" text @click="handleDeleteCategory(category)">
                  <el-icon><Delete /></el-icon> 删除
                </el-button>
              </div>
            </div>
          </el-card>
        </el-col>
      </el-row>
      
      <!-- 空状态 -->
      <el-empty 
        v-if="categories.length === 0 && !loading" 
        description="暂无景点类别数据" 
      >
        <el-button type="primary" @click="handleAddCategory">添加类别</el-button>
      </el-empty>
    </div>
    
    <!-- 分页 -->
    <div class="pagination-container" v-if="total > 0">
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="[8, 16, 24, 32]"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
    
    <!-- 类别编辑对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="isEdit ? '编辑景点类别' : '添加景点类别'"
      width="600px"
      destroy-on-close
    >
      <el-form
        ref="categoryFormRef"
        :model="categoryForm"
        :rules="categoryRules"
        label-width="100px"
      >
        <el-form-item label="类别名称" prop="categoryName">
          <el-input v-model="categoryForm.categoryName" placeholder="请输入类别名称" />
        </el-form-item>
        
        <el-form-item label="排序顺序" prop="sortOrder">
          <el-input-number 
            v-model="categoryForm.sortOrder" 
            :min="0" 
            :max="999" 
            :step="1"
            placeholder="数值越小排序越靠前"
          />
          <div class="form-tip">数值越小，在列表中显示越靠前</div>
        </el-form-item>
        
        <el-form-item label="是否热门" prop="isHot">
          <el-switch
            v-model="categoryForm.isHot"
            active-text="热门"
            inactive-text="普通"
          />
        </el-form-item>
        
        <el-form-item label="封面图片" prop="coverImage">
          <el-upload
            class="cover-uploader"
            :action="uploadAction"
            :headers="uploadHeaders"
            :show-file-list="false"
            :before-upload="beforeUpload"
            :on-success="handleUploadSuccess"
            :on-error="handleUploadError"
          >
            <img v-if="categoryForm.coverImage" :src="categoryForm.coverImage" class="cover-preview" />
            <el-icon v-else class="cover-uploader-icon"><Plus /></el-icon>
          </el-upload>
          <div class="upload-tip">建议上传16:9比例图片，最佳尺寸为800x450像素</div>
        </el-form-item>
        
        <el-form-item label="类别描述" prop="description">
          <el-input
            v-model="categoryForm.description"
            type="textarea"
            :rows="4"
            placeholder="请输入类别描述"
            maxlength="500"
            show-word-limit
          />
        </el-form-item>
      </el-form>
      
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitCategoryForm" :loading="submitting">
            确认
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { Search, Plus, Edit, Delete } from '@element-plus/icons-vue';
import { 
  getAllCategories, 
  getCategoryList, 
  addCategory, 
  updateCategory, 
  deleteCategory,
  uploadCategoryImage
} from '@/api/category';

// 状态变量
const loading = ref(false);
const categories = ref([]);
const total = ref(0);
const currentPage = ref(1);
const pageSize = ref(8);
const searchQuery = ref('');
const hotFilter = ref('');
const dialogVisible = ref(false);
const submitting = ref(false);
const isEdit = ref(false);

// 默认封面图
const defaultCover = 'https://via.placeholder.com/800x450?text=No+Image';

// 上传相关
const uploadAction = `${import.meta.env.VITE_API_BASE_URL}/category/upload/cover`;
const uploadHeaders = computed(() => {
  return {
    Authorization: `Bearer ${localStorage.getItem('token')}`
  };
});

// 类别表单
const categoryFormRef = ref(null);
const categoryForm = reactive({
  categoryId: null,
  categoryName: '',
  sortOrder: 0,
  isHot: false,
  coverImage: '',
  description: ''
});

// 表单验证规则
const categoryRules = {
  categoryName: [
    { required: true, message: '请输入类别名称', trigger: 'blur' },
    { min: 2, max: 20, message: '长度在2到20个字符之间', trigger: 'blur' }
  ],
  sortOrder: [
    { required: true, message: '请输入排序权重', trigger: 'blur' }
  ],
  description: [
    { max: 500, message: '描述不能超过500个字符', trigger: 'blur' }
  ]
};

// 格式化日期
const formatDate = (dateString) => {
  if (!dateString) return '';
  const date = new Date(dateString);
  return date.toLocaleDateString();
};

// 获取类别列表
const fetchCategories = async () => {
  loading.value = true;
  try {
    const params = {
      pageNum: currentPage.value,
      pageSize: pageSize.value,
      sort: 'sortOrder', // 按sortOrder字段排序
      order: 'asc'       // 升序排列，数值小的在前
    };
    
    // 添加搜索条件
    if (searchQuery.value) {
      params.categoryName = searchQuery.value;
    }
    
    // 添加热门筛选
    if (hotFilter.value !== '') {
      params.isHot = hotFilter.value;
    }
    
    const response = await getCategoryList(params);
    
    if (response.code === 200 && response.data) {
      categories.value = response.data.list;
      total.value = response.data.total;
    } else {
      ElMessage.error(response.message || '获取类别列表失败');
    }
  } catch (error) {
    console.error('获取类别列表失败:', error);
    ElMessage.error('获取类别列表失败，请稍后再试');
  } finally {
    loading.value = false;
  }
};

// 搜索
const handleSearch = () => {
  currentPage.value = 1;
  fetchCategories();
};

// 重置搜索
const resetSearch = () => {
  searchQuery.value = '';
  hotFilter.value = '';
  currentPage.value = 1;
  fetchCategories();
};

// 添加类别
const handleAddCategory = () => {
  isEdit.value = false;
  // 重置表单
  Object.keys(categoryForm).forEach(key => {
    categoryForm[key] = key === 'sortOrder' ? 0 : key === 'isHot' ? false : '';
  });
  dialogVisible.value = true;
};

// 编辑类别
const handleEditCategory = (category) => {
  isEdit.value = true;
  // 复制类别数据到表单
  Object.keys(categoryForm).forEach(key => {
    if (key in category) {
      categoryForm[key] = category[key];
    }
  });
  dialogVisible.value = true;
};

// 删除类别
const handleDeleteCategory = (category) => {
  ElMessageBox.confirm(
    `确定要删除类别 "${category.categoryName}" 吗？删除后无法恢复，且可能影响关联的景点。`,
    '警告',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  )
    .then(async () => {
      try {
        const response = await deleteCategory(category.categoryId);
        
        if (response.code === 200) {
          ElMessage.success('删除类别成功');
          fetchCategories();
        } else {
          ElMessage.error(response.message || '删除类别失败');
        }
      } catch (error) {
        console.error('删除类别失败:', error);
        ElMessage.error('删除类别失败，请稍后再试');
      }
    })
    .catch(() => {
      // 用户取消操作
    });
};

// 上传前验证
const beforeUpload = (file) => {
  const isImage = file.type.startsWith('image/');
  const isLt5M = file.size / 1024 / 1024 < 5;

  if (!isImage) {
    ElMessage.error('只能上传图片文件!');
    return false;
  }
  if (!isLt5M) {
    ElMessage.error('图片大小不能超过5MB!');
    return false;
  }
  return true;
};

// 上传成功回调
const handleUploadSuccess = (response) => {
  if (response.code === 200 && response.data) {
    categoryForm.coverImage = response.data.url;
    ElMessage.success('图片上传成功');
  } else {
    ElMessage.error(response.message || '图片上传失败');
  }
};

// 上传失败回调
const handleUploadError = (error) => {
  console.error('图片上传失败:', error);
  ElMessage.error('图片上传失败，请稍后再试');
};

// 提交类别表单
const submitCategoryForm = () => {
  categoryFormRef.value.validate(async (valid) => {
    if (valid) {
      submitting.value = true;
      try {
        const submitData = {
          categoryName: categoryForm.categoryName,
          sortOrder: categoryForm.sortOrder,
          isHot: categoryForm.isHot,
          coverImage: categoryForm.coverImage,
          description: categoryForm.description
        };
        
        let response;
        if (isEdit.value) {
          // 编辑模式
          submitData.categoryId = categoryForm.categoryId;
          response = await updateCategory(submitData);
        } else {
          // 添加模式
          response = await addCategory(submitData);
        }
        
        if (response.code === 200) {
          ElMessage.success(isEdit.value ? '更新类别成功' : '添加类别成功');
          dialogVisible.value = false;
          fetchCategories();
        } else {
          ElMessage.error(response.message || (isEdit.value ? '更新类别失败' : '添加类别失败'));
        }
      } catch (error) {
        console.error(isEdit.value ? '更新类别失败:' : '添加类别失败:', error);
        ElMessage.error(error.message || (isEdit.value ? '更新类别失败' : '添加类别失败'));
      } finally {
        submitting.value = false;
      }
    }
  });
};

// 分页大小变化
const handleSizeChange = (size) => {
  pageSize.value = size;
  fetchCategories();
};

// 页码变化
const handleCurrentChange = (page) => {
  currentPage.value = page;
  fetchCategories();
};

onMounted(() => {
  fetchCategories();
});
</script>

<style scoped>
.category-management {
  padding: 20px;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.title-section h1 {
  margin: 0;
  font-size: 28px;
  color: #303133;
  font-weight: 600;
}

.subtitle {
  margin: 8px 0 0;
  color: #909399;
  font-size: 14px;
}

.filter-card {
  margin-bottom: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
}

.filter-container {
  display: flex;
  gap: 15px;
  flex-wrap: wrap;
}

.search-input {
  width: 300px;
}

.category-list {
  margin-bottom: 20px;
}

.category-card {
  margin-bottom: 20px;
  border-radius: 8px;
  overflow: hidden;
  transition: all 0.3s;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.category-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
}

.category-cover {
  position: relative;
  height: 150px;
  overflow: hidden;
}

.category-cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.3s;
}

.category-card:hover .category-cover img {
  transform: scale(1.05);
}

.category-badge {
  position: absolute;
  top: 10px;
  right: 10px;
}

.category-info {
  padding: 15px;
  flex: 1;
  display: flex;
  flex-direction: column;
}

.category-info h3 {
  margin: 0 0 10px;
  font-size: 18px;
  font-weight: 600;
  color: #303133;
}

.category-description {
  color: #606266;
  font-size: 14px;
  margin-bottom: 15px;
  flex: 1;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}

.category-meta {
  display: flex;
  justify-content: space-between;
  color: #909399;
  font-size: 12px;
  margin-bottom: 10px;
}

.category-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: center;
}

.cover-uploader {
  width: 300px;
  height: 169px;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
}

.cover-uploader:hover {
  border-color: #409EFF;
}

.cover-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 28px;
  height: 28px;
}

.cover-preview {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.upload-tip {
  font-size: 12px;
  color: #909399;
  margin-top: 5px;
}

.form-tip {
  font-size: 12px;
  color: #909399;
  margin-top: 5px;
}

@media (max-width: 768px) {
  .page-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 15px;
  }
  
  .filter-container {
    flex-direction: column;
  }
  
  .search-input {
    width: 100%;
  }
}
</style> 